package com.xiaoc.bulldozer.facade.impl;

import com.xiaoc.bulldozer.common.dto.MenuNode;
import com.xiaoc.bulldozer.common.dto.MenuNode.Node;
import com.xiaoc.bulldozer.common.model.*;
import com.xiaoc.bulldozer.common.service.*;
import com.xiaoc.bulldozer.common.service.cache.PriviledgeCacheService;
import com.xiaoc.bulldozer.common.service.cache.UserRoleCacheService;
import com.xiaoc.bulldozer.facade.PriviledgeFacade;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service("priviledgeFacade")
public class PriviledgeFacadeImpl implements PriviledgeFacade {

    @Resource
    private RoleService roleService;

    @Resource(name = "priviledgeService")
    private PriviledgeService priviledgeService;

    @Resource(name = "priviledgeService")
    private PriviledgeCacheService priviledgeCacheService;

    @Resource
    private ActionService actionService;

    @Resource
    private UserRoleService userRoleService;

    @Resource
    private UserRoleCacheService userRoleCacheService;

    @Resource(name = "dataPriviledgeService")
    private DataPriviledgeService dataPriviledgeService;

    @Override
    public Map<Integer, Map<String, Object>> getAllRolePriviledge() {

        Map<Integer, Map<String, Object>> priviledgeMap = new HashMap<Integer, Map<String, Object>>();

        // 获取全部权限
        List<Priviledge> priviledgeList = priviledgeService.getAll();

        // 如果没有权限，则直接返回
        if (priviledgeList == null || priviledgeList.size() == 0) {
            return priviledgeMap;
        }

        // 按照角色进行权限分组
        Map<Integer, List<Integer>> roleActionMap = assemblePriviledge(priviledgeList);

        for (Integer roleId : roleActionMap.keySet()) {
            List<Action> roleActionList = actionService.getActionListByIds(roleActionMap.get(roleId));
            Map<String, Object> roleActionDataMap = assembelAction(roleActionList);
            priviledgeMap.put(roleId, roleActionDataMap);
        }

        return priviledgeMap;
    }

    @Override
    public Map<Integer, Priviledge> getPrivildegeByRoleId(Integer roleId) {

        Map<Integer, Priviledge> priviledgeMap = new HashMap<Integer, Priviledge>();

        // 获取全部权限
        List<Priviledge> priviledgeList = priviledgeService.getPriviledgeListByRoleId(roleId);
        for (Priviledge priviledge : priviledgeList) {
            priviledgeMap.put(priviledge.getActionId(), priviledge);
        }

        return priviledgeMap;

    }

    /**
     * 按照 roleId 分组 priviledge
     * 
     * @param priviledgeList
     * @return
     */
    private Map<Integer, List<Integer>> assemblePriviledge(List<Priviledge> priviledgeList) {

        Map<Integer, List<Integer>> roleActionMap = new HashMap<Integer, List<Integer>>();

        // 如果权限列表为空，则直接返回。
        if (priviledgeList == null) {
            return roleActionMap;
        }

        for (Priviledge priviledge : priviledgeList) {

            // 从 map中取出角色对应的权限，如果不存在，则新建一个角色权限List。
            List<Integer> roleActionList = roleActionMap.get(priviledge.getRoleId());
            if (roleActionList == null) {
                roleActionList = new ArrayList<Integer>();
            }

            roleActionList.add(priviledge.getActionId());
            roleActionMap.put(priviledge.getRoleId(), roleActionList);
        }

        return roleActionMap;

    }

    /**
     * 按照 menu 分组 action
     * 
     * @param actionList
     * @return
     */
    public Map<String, Object> assembelAction(List<Action> actionList) {

        List<Action> rootMenuActionList = new ArrayList<Action>();
        Map<Integer, List<Action>> subMenuActionMap = new HashMap<Integer, List<Action>>();
        Map<Integer, List<Action>> leafActionMap = new HashMap<Integer, List<Action>>();

        for (Action action : actionList) {

            // 根菜单
            if (action.getIsMenu() == Action.IS_MENU_YES && action.getParentId() == Action.ROOT_MENU) {
                rootMenuActionList.add(action);
                continue;
            }

            // 子菜单
            if (action.getIsMenu() == Action.IS_MENU_YES && action.getParentId() != Action.ROOT_MENU) {
                List<Action> subMenuActionList = subMenuActionMap.get(action.getParentId());
                if (subMenuActionList == null) {
                    subMenuActionList = new ArrayList<Action>();
                    subMenuActionList.add(action);
                    subMenuActionMap.put(action.getParentId(), subMenuActionList);
                    continue;
                }

                subMenuActionMap.get(action.getParentId()).add(action);
            }

            // 叶子操作
            if (action.getIsMenu() != Action.IS_MENU_YES && action.getParentId() != Action.ROOT_MENU) {
                List<Action> leafMenuActionList = leafActionMap.get(action.getParentId());
                if (leafMenuActionList == null) {
                    leafMenuActionList = new ArrayList<Action>();
                    leafMenuActionList.add(action);
                    leafActionMap.put(action.getParentId(), leafMenuActionList);
                    continue;
                }

                leafActionMap.get(action.getParentId()).add(action);
            }
        }

        Map<String, Object> actionDataMap = new HashMap<String, Object>();
        actionDataMap.put("rootMenuActionList", rootMenuActionList);
        actionDataMap.put("subMenuActionMap", subMenuActionMap);
        actionDataMap.put("leafActionMap", leafActionMap);

        return actionDataMap;
    }

    @Override
    public Map<String, Object> getAllAction() {

        List<Action> actionList = actionService.getAll();

        if (actionList == null || actionList.size() == 0) {
            return new HashMap<String, Object>();
        }

        return assembelAction(actionList);
    }

    @Override
    public void updateRolePriviledge(Integer[] actionIdArr, Role role) {
        // 如果 action 为空，说明清空所有权限
        if (actionIdArr == null || actionIdArr.length == 0) {
            priviledgeService.deleteBatch(role.getId());
            return;
        }

        Integer validActionCount = actionService.getVaildActionCountByIds(actionIdArr);

        // 判断是否有非法的 action
        if (actionIdArr.length != validActionCount) {
            return;
        }

        // 删除老的角色权限，并增加新的角色权限
        priviledgeService.deleteBatch(role.getId());
        priviledgeService.addBatch(actionIdArr, role.getId());
    }

    @Override
    public List<Action> getActionListByUserId(User user) {

        if (user == null) {
            return Collections.EMPTY_LIST;
        }

        List<UserRole> roleList = userRoleService.getUserRoleListByUserId(user.getId());
        if (CollectionUtils.isEmpty(roleList)) {
            return Collections.EMPTY_LIST;
        }

        List<Integer> roleIdList = new ArrayList<Integer>();
        for (UserRole userRole : roleList) {
            roleIdList.add(userRole.getRoleId());
        }

        return priviledgeCacheService.getActionListByRoleIdList(roleIdList);
    }

    @Override
    public List<MenuNode> getMenuTree(User user, Integer system) {
        List<Action> actionList = this.getActionListByUserId(user);

        // 过滤出菜单项
        List<Action> menuActionList = new ArrayList<Action>(actionList.size());
        List<Action> rootMenuActionList = new ArrayList<Action>(actionList.size());
        for (Action action : actionList) {
            if (action == null || action.getIsMenu().intValue() != Action.IS_MENU_YES || !action.getSystem().equals(system)) {
                continue;
            }

            menuActionList.add(action);
            if (action.getParentId() == Action.ROOT_MENU) {
                rootMenuActionList.add(action);
            }
        }

        // 构造菜单tree
        List<MenuNode> menuNodeList = new ArrayList<MenuNode>();
        for (Action rootMenuAction : rootMenuActionList) {
            MenuNode menuNode = new MenuNode();
            Node rootNode = this.structureNode(rootMenuAction);

            // 处理二级菜单
            if (!rootNode.isLeaf()) {
                List<Node> subNodeList = this.dealSubNodeList(rootMenuAction, menuActionList);
                menuNode.setSubNodeList(subNodeList);
            }

            menuNode.setCurNode(rootNode);
            menuNodeList.add(menuNode);
        }

        return menuNodeList;
    }

    /**
     * 构造节点
     * 
     * @param menuAction
     * @return
     */
    private Node structureNode(Action menuAction) {
        Node node = new Node();
        node.setId(menuAction.getId());
        node.setName(menuAction.getName() + (StringUtils.isEmpty(menuAction.getAliasName()) ? "" : ("(" + menuAction.getAliasName() + ")")));
        node.setUrl(menuAction.getUrl());
        node.setLeaf(StringUtils.isNotEmpty(menuAction.getUrl()));

        return node;
    }

    /**
     * 处理二级菜单
     * 
     * @param rootMenuAction
     * @param menuActionList
     * @return
     */
    private List<Node> dealSubNodeList(Action rootMenuAction, List<Action> menuActionList) {
        List<Node> subNodeList = new ArrayList<Node>();
        for (Action action : menuActionList) {
            if (action.getParentId().equals(rootMenuAction.getId())) {
                subNodeList.add(this.structureNode(action));
            }
        }
        return subNodeList;
    }

    @Override
    public List<DataPriviledge> getDataPrivildegeByUserAndType(User user, Integer type) {

        if (user == null) {
            return Collections.EMPTY_LIST;
        }

        List<Integer> roleIdList = userRoleCacheService.getRoleIdListByUserId(user.getId());
        if (CollectionUtils.isEmpty(roleIdList)) {
            return Collections.EMPTY_LIST;
        }

        return dataPriviledgeService.getDataPriviledgeListByRoleIdListAndType(roleIdList, type);
    }
}
